<template>
	<view id="navigatorMenu" class="navigator-menu" v-if="list&&list.length">
		<scroll-view scroll-x class="scroll-view" :style="{width: wrapWidth}" @scroll="scrolling" scroll-with-animation>
			<view class="scroll-container" :class="{'is-fix':!fix}">
				<!--导航-->
				<view class="menu-container" :id="'navigatorMenu-item-'+index" v-for="(item,index) in list" :key="index">
					<template>
						<view class="menu-item" :open-type="item[openTypeFieldName]" @click="onClick" :class="{'click-feedback':clickFeedback}"
						 :data-item="stringifyItem(item)">
							<!--图标-->
							<view>
								<view class="menu-icon">
									<template>
										<view class="menu-icon-container">
											<view class="menu-icon-body">
												<image lazy-load mode="aspectFit" :src="item[iconFieldName]" v-if="item[iconFieldName]"></image>
											</view>
										</view>
									</template>
								</view>
							</view>
							<!--文本-->
							<view class="menu-title" v-if="item[nameFieldName]&&!$slots.title" :style="{color:item.titleColor||textColor}"
							 v-html="item[nameFieldName]"></view>
						</view>
					</template>
				</view>
			</view>
		</scroll-view>
		<!--滚动条-->
		<view v-if="isScroll&&showScrollBar" class="scroll-bar-wrap">
			<view class="scroll-groove ">
				<view class="scroll-bar " :style="{transform: 'translateX('+barScrollLeft+')'}"></view>
			</view>
		</view>
	</view>
</template>
<script>
	// 需要安装依赖 npm i -S numeral
	import numeral from 'numeral'
	export default {
		props: {
			// 列表，必填
			list: {
				type: Array,
				required: true,
				default: []
			},
			//名称key
			nameFieldName: {
				type: String,
				default: 'title'
			},
			//图标的key
			iconFieldName: {
				type: String,
				default: 'icon'
			},
			// 跳转链接的key，可选
			urlFieldName: {
				type: String,
				default: 'url'
			},
			//开放能力
			openTypeFieldName: {
				type: String,
				default: 'openType'
			},
			// 文本颜色
			textColor: {
				type: String,
				default: '#666'
			},
			// 图标颜色
			iconColor: {
				type: String,
				default: '#666'
			},
			// 行数
			rowCount: {
				type: Number | String,
				default: 2
			},
			// 列数
			colCount: {
				type: Number | String,
				default: 4
			},
			// 图标宽高
			size: {
				type: String,
				default: '60rpx'
			},
			// 每一个菜单的高度，不设置则为内容高度，所有菜单高度统一
			height: {
				type: String,
				default: ''
			},
			// 点击反馈
			clickFeedback: {
				type: Boolean,
				default: true
			},
			//当出现横向滚动时，是否显示指示条
			showScrollBar: {
				type: Boolean,
				default: true
			},
			//项目内，承载一个webview用于外部链接展示的页面路径，如果菜单项是跳转外部链接，h5直接location.href，app和小程序跳转webview
			webview: String
		},
		data() {
			return {
				wrapWidth: null,
				itemWidth: null,
				itemHeight: '',
				barScrollLeft: null,
				show: false,
				containerHeight: 170,
				isScroll: false,
				rpxToPxFactor: 0
			}
		},
		computed: {
			iconSize: function() {
				return /(px|rpx|em|pt)/.test(this.size) ? this.size : numeral(this.size.replace(/(px|rpx|em|pt)/g, '')).multiply(
					this.rpxToPxFactor).value() + 'px'
			},
			fix: function() {
				return this.list.length <= this.rowCount * this.colCount
			},
			wrapHeight: function() {
				return this.fix ? 'auto' : (this.containerHeight || 0)
			}
		},
		mounted() {
			this.getSystemInfo()
			setTimeout(() => {
				this.init()
			}, 10)
		},
		methods: {
			//格式化为字符串
			stringifyItem(item) {
				return JSON.stringify(item)
			},
			/**
			 * 将全局的像素比例设置，调整到组件内部
			 * */
			getSystemInfo() {
				const that = this
				uni.getSystemInfo({
					success: function(e) {
						// 根据安全屏幕宽度，设置rpx和px的比例，比例尺参考微信小程序 1rpx=n px
						that.rpxToPxFactor = e.safeArea.width < 375 ? 0.42 : (e.safeArea.width > 375 ? .552 : .5)
					}
				})
			},
			/*
			 * 初始化
			 * */
			init() {
				const that = this
				if (!that.list || !that.list.length) return

				let query = uni.createSelectorQuery().in(that)
				let node = query.select(`#navigatorMenu-item-0`).boundingClientRect()

				node = query.select('#navigatorMenu').boundingClientRect()
				node.exec(result => {
					let [container, wrap] = result
					// // 取余，如果list长度大于行x列，且有余数，滚动的宽度为单行数量+1，否则，就等于单行数量
					let more_col = that.list.length > (that.rowCount * that.colCount) && that.list.length % (that.rowCount * that.colCount) === 0;
					// //单个宽度
					let itemWidth = `${numeral(wrap.width).divide(that.colCount).value()}px`
					let wrapWidth = `${more_col ? wrap.width : wrap.width}px`
					that.wrapWidth = wrapWidth
					let isScroll = that.list.length > (that.rowCount * that.colCount)
					that.isScroll = isScroll
					wrapWidth = null
				})
			},
			/**
			 * 滚动事件
			 * @param e
			 */
			scrolling(e) {
				const that = this
				//如果没有开启指示条，不执行滚动监听
				if (!that.showScrollBar) {
					return
				}
				let {
					scrollLeft,
					scrollWidth
				} = e.detail
				// 可滚动区域
				let canScrollWidth = numeral(scrollWidth).subtract(that.wrapWidth.substring(0, that.wrapWidth.length - 2)).value()
				let scale = numeral(scrollLeft).divide(canScrollWidth).value()
				// 可滚动区域
				let grooveW = 30
				// 计算滚动条可滚动区域
				that.barScrollLeft = `${numeral(scale).multiply(grooveW).value()}px`
			},
			/**
			 * 菜单触发的事件
			 * @param e
			 */
			onClick(e) {
				const that = this
				let item = JSON.parse(e.currentTarget.dataset.item)
				that.$emit('press', item)
			}
		}
	}
</script>
<style lang="scss" scoped>
	@function units($val) {
		@return $val*2rpx;
	}

	view,
	button,
	scroll-view,
	text {
		box-sizing: border-box;
		line-height: 1;
	}

	.scroll-container {
		height: 340rpx;
		white-space: nowrap;
		display: flex;
		flex-wrap: wrap;

		&.is-fix {
			flex-direction: column;
		}
	}

	.menu-container {
		position: relative;
		margin-top: 20rpx;

		.menu-item {
			width: 140rpx;
			height: 140rpx;
			display: flex;
			align-items: center;
			flex-direction: column;
			background-color: transparent;
		}
	}

	.scroll-groove {
		width: 108rpx;
		height: 12rpx;
		border-radius: 100vw;
		background-color: #f1f4f7;
		overflow: hidden;

		.scroll-bar {
			width: 40rpx;
			height: 100%;
			border-radius: 100vw;
			background-color: red;
		}
	}

	.scroll-view {
		width: 100%;
	}

	.menu-icon {
		position: relative;
		overflow: hidden;
		width: 80rpx;
		height: 80rpx;
		margin-bottom: 20rpx;

		&-container {
			height: 0;
			padding-bottom: 100%;
		}

		&-body {
			position: absolute;
			left: 0;
			top: 0;
			width: 100%;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: center;

			image {
				width: 100%;
				height: 100%;
			}
		}

		&-placeholder {
			background-color: #eee;
			color: #f1f4f7;
			font-size: 30%;
		}
	}

	// 菜单标题
	.menu-title {
		font-size: units(12);
		margin-top: units(5);
	}

	.scroll-bar-wrap {
		display: flex;
		align-items: center;
		justify-content: center;
		padding-bottom: units(5);
	}
</style>
